package com.example.demo.service.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.example.demo.dao.DakaCountDao;
import com.example.demo.dao.QuerybyaccountandmacDao;
import com.example.demo.dao.QuerydakamingxiandbydatebymacDao;
import com.example.demo.entity.*;
import com.example.demo.dao.DakamingxiDao;
import com.example.demo.service.DakamingxiService;
import com.example.demo.util.DateUtil;
import com.example.demo.util.LoginAuthUtil;
import com.example.demo.util.RestHttp;
import com.example.demo.util.StringUtils;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.example.demo.util.Distinct.distinctByKey;


/**
 * (Dakamingxi)表服务实现类
 *
 * @author makejava
 * @since 2020-04-03 11:12:13
 */
@Service("dakamingxiService")
public class DakamingxiServiceImpl implements DakamingxiService {
    @Resource
    private DakamingxiDao dakamingxiDao;
    @Resource
    private DakaCountDao dakaCountDao;
    @Autowired
    LoginAuthUtil loginAuthUtil;
    @Resource
    private QuerybyaccountandmacDao querybyaccountandmacDao;
    @Resource
    private QuerydakamingxiandbydatebymacDao querydakamingxiandbydatebymacDao;
    @Autowired
    RestHttp restHttp;


    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public Dakamingxi queryById(Integer id) {
        return this.dakamingxiDao.queryById(id);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @Override
    public List<Dakamingxi> queryAllByLimit(int offset, int limit) {
        return this.dakamingxiDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param dakamingxi 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional
    public Dakamingxi insert(Dakamingxi dakamingxi) {
        this.dakamingxiDao.insert(dakamingxi);
        return dakamingxi;
    }

    /**
     * 修改数据
     *
     * @param dakamingxi 实例对象
     * @return 实例对象
     */
    @Override
    public Dakamingxi update(Dakamingxi dakamingxi) {
        this.dakamingxiDao.update(dakamingxi);
        return this.queryById(dakamingxi.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.dakamingxiDao.deleteById(id) > 0;
    }

    /**
     *
     * @param mac 账号
     * @param date  当前日期
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     * @throws KeyManagementException
     */
    @Override
    public List<Querybyaccountandmac> queryByAccount(String mac,String date) throws IOException,
            NoSuchAlgorithmException, KeyStoreException, KeyManagementException, ParseException
    {
        List<Dakamingxi> dtoList=new ArrayList<>();
        List<Dakamingxi> dtoList1=new ArrayList<>();
        List<Querybyaccountandmac> querybyaccountandmacList=null;
        Map<String,List<Dakamingxi>> map=loginAuthUtil.redis();
        if (!map.isEmpty()){
            dtoList= map.get("dtoList");
            dtoList1= map.get("dtoList1");
        }

       // List<Dakamingxi> dtoList=loginAuthUtil.redis(); //发起云管理通信
        DakaCount dakaCount = dakaCountDao.count(new Date());
        System.out.println(date);
        if(dakaCount==null){
            dakaCount.setApp(1);
            dakaCount= new DakaCount();
            dakaCount.setCjsj(date);
            dakaCount.setFwcs(1);
            dakaCount.setTxcs(1);
            dakaCount.setMac(mac);
            dakaCountDao.insert(dakaCount);//插入
        }else{
            String countMac = dakaCount.getMac();
            if( countMac==null || countMac.indexOf(mac)==-1){
                dakaCount.setApp(dakaCount.getApp()+1);
                StringBuffer sb= new StringBuffer(countMac==null?"":countMac);
                String string = sb.append(",").append(mac).toString();
                dakaCount.setMac(string);
            }
            dakaCount.setFwcs(dakaCount.getFwcs()+1);
            dakaCountDao.update(dakaCount);//更新
        }
        if (dtoList.size()==0)
        {
            if (dtoList1.size()==0)
            {
                return queryByDate(date);
            } else {
                updateDakmingxi(dtoList1);
                return queryByDate(date);
            }
        } else {
            insertDakmingxi(dtoList);  // 插入数据库
            if (dtoList1.size()==0)
            {
                return queryByDate(date);
            } else {
                updateDakmingxi(dtoList1);
            }
            querybyaccountandmacList=queryByDate(date);//查询
            return querybyaccountandmacList;
        }
    }
    /**
     * 更新数据库
     * @param dtoList
     */
    @Transactional
    public void updateDakmingxi(List<Dakamingxi> dtoList) {
        LocalDate localDate=LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");//获得当前日期
        List<Dakamingxi> dakamingxiList=new ArrayList<>();//插入
        List<Dakamingxi> dakamingxiList1=new ArrayList<>();//更新
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (Dakamingxi dakamingxi:dtoList)
        {
            //当前日期内 数据库是否已经插入数据
            Dakamingxi dakamingxi1= dakamingxiDao.queryByAccount(dakamingxi.getAccount(),localDate.format(formatter));
            if (dakamingxi1==null){
                dakamingxiList.add(dakamingxi);
            }else {
                try {
                    if (dakamingxi1.getEndtime()==null)
                    {
                        // 比较 数据库的时间和用户的时间，取小的时间对数据库更新
                        dakamingxiList1.add(dakamingxi);
                    }else {
                        if (sdf.parse(dakamingxi1.getEndtime()).getTime()<sdf.parse(dakamingxi.getEndtime()).getTime())
                        {
                            // 比较 数据库的时间和用户的时间，取小的时间对数据库更新
                            dakamingxiList1.add(dakamingxi);
                        }
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
        if (dakamingxiList.size()>0)
        {
            //插入到list对象不能为空  插入下班时间
            dakamingxiDao.insertList(dakamingxiList);
        }

        if (dakamingxiList1.size()>0)
        {
            //插入到list对象不能为空 更新下班时间
            dakamingxiDao.updateList(dakamingxiList1);
        }
    }

    /**
     *查询querybyaccountandmac下的数据
     * @param mac
     * @param format
     * @return
     */
    @Override
    public List<Querybyaccountandmac> queryByAndMacDate(String mac, String format) {
        List<Querybyaccountandmac> querybyaccountandmacList= querybyaccountandmacDao.queryByAndViewMacDate(mac,format);
        return querybyaccountandmacList;
    }


    /**
     * 查询上一日数据
     * 查询下一日数据
     * @param mac
     * @param yesDay
     * @param nextDay
     * @return
     */
    @Override
    public List<Querybyaccountandmac> queryByAndMacDate(String mac, String yesDay,String nextDay) {
        List<Querybyaccountandmac> querybyaccountandmacList=null;
        if (!yesDay.isEmpty()){
            querybyaccountandmacList=  querybyaccountandmacDao.queryByAndViewMacDate(mac,yesDay);
        }
        if (!nextDay.isEmpty()){
            querybyaccountandmacList= querybyaccountandmacDao.queryByAndViewMacDate(mac,nextDay);
        }

        return querybyaccountandmacList;
    }

    /**
     * 查询querybyaccountandmac下的数据
     * @param format
     * @return
     */
    @Override
    public List<Querybyaccountandmac> queryByDate(String format)
    {
        List<Querybyaccountandmac> querybyaccountandmacList= querybyaccountandmacDao.queryByViewDate(format);
        return querybyaccountandmacList;
    }

    /**
     * 查询上一日数据
     * 查询下一日数据
     * @param yesDay
     * @param nextday
     * @return
     */
    @Override
    public List<Querybyaccountandmac> queryByDate(String yesDay, String nextday) {
        List<Querybyaccountandmac> querybyaccountandmacList=null;
        if (!yesDay.isEmpty())
        {
            querybyaccountandmacList=querybyaccountandmacDao.queryByViewDate(yesDay);

        }
        if (!nextday.isEmpty())
        {
            querybyaccountandmacList=querybyaccountandmacDao.queryByViewDate(nextday);
        }
        return querybyaccountandmacList;
    }

    /**
     * 插入数据库
     * @param dtoList
     */
    @Override
    @Transactional
    public void insertDakmingxi(List<Dakamingxi> dtoList) {
        LocalDate localDate=LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");//获得当前日期
        List<Dakamingxi> dakamingxiList=new ArrayList<>();//插入
        List<Dakamingxi> dakamingxiList1=new ArrayList<>();//更新
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (Dakamingxi dakamingxi:dtoList)
        {
            //当前日期内 数据库是否已经插入数据
            Dakamingxi dakamingxi1= dakamingxiDao.queryByAccount(dakamingxi.getAccount(),localDate.format(formatter));
            if (dakamingxi1==null){
                dakamingxiList.add(dakamingxi);
            }else {
                try {
                    // 比较 数据库的时间和用户的时间，取小的时间对数据库更新
                    if (sdf.parse(dakamingxi1.getFirsttime()).getTime()>sdf.parse(dakamingxi.getFirsttime()).getTime())
                    {
                        dakamingxiList1.add(dakamingxi);
                    }

                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
        if (dakamingxiList.size()>0)
        {
            //插入到list对象不能为空
          dakamingxiDao.insertList(dakamingxiList);
        }

        if (dakamingxiList1.size()>0)
        {
            //插入到list对象不能为空
          dakamingxiDao.updateList(dakamingxiList1);
        }
    }

    @Override
    public List<Querybyaccountandmac> queryByTwoDate(String account, String lastweek) {
        return null;
    }

    /**
     * 下载
     * @param uId
     * @param endDate
     * @param mac
     * @param svcID
     * @param startDate
     * @param account
     * @return
     */
    @Override
    public byte[] exportDaKaMingXi(String uId, String endDate, String mac, String svcID, String startDate, String account) {
        ExcelWriter writer = ExcelUtil.getWriter(true);
        Map<String, String> map = MapUtil.newHashMap(true);
        map.put("departName","部门");
        map.put("uname","姓名");
        map.put("account","账号");
        map.put("clockin","上班打卡时间");
        map.put("clockout","下班打卡时间");
        map.put("dayOfWeek","星期");
        map.put("cDate", "日期");
        map.put("sitename", "站点名称");
        map.put("deviceid", "设备");
        writer.setHeaderAlias(map);
        List<DownlaodExcelDaKaMingXi> querydakamingxiandbydatebymacList1 = new ArrayList<>();// 一次性写出内容，使用默认样式
        List<Querydakamingxiandbydatebymac>  querydakamingxiandbydatebymacList=null;
        if(account.equals("0")){
            querydakamingxiandbydatebymacList=querydakamingxiandbydatebymacDao.queryDakamingxiandbyWeek(startDate,endDate);
//        }else if(account.equals("0")){
//            querydakamingxiandbydatebymacList=querydakamingxiandbydatebymacDao.queryDakamingxiandbyBydate(startDate);
        }else {
            querydakamingxiandbydatebymacList=querydakamingxiandbydatebymacDao.queryDakamingxiandbyWeekbymac(account,mac,startDate,endDate);
        }
        querydakamingxiandbydatebymacList.stream().forEach(querydakamingxiandbydatebymac -> {
            DownlaodExcelDaKaMingXi querybyaccountandmac1=new DownlaodExcelDaKaMingXi();
            if (querydakamingxiandbydatebymac.getUname()==null){
                querybyaccountandmac1.setUname(querydakamingxiandbydatebymac.getMac().trim().replace("-",":"));
            }else {
                querybyaccountandmac1.setUname(querydakamingxiandbydatebymac.getUname());
            }

            if (querydakamingxiandbydatebymac.getClockout()!=null)
            {
                //截取字符串  ，取时分秒
                querybyaccountandmac1.setClockout(querydakamingxiandbydatebymac.getClockout().toString().trim().substring(10,19));;
            } else {
                querybyaccountandmac1.setClockout(null);
            }
            if (querydakamingxiandbydatebymac.getClockin()!=null)
            {
                //截取字符串  ，取时分秒
                querybyaccountandmac1.setClockin(querydakamingxiandbydatebymac.getClockin().toString().trim().substring(10,19));
            } else {
                querybyaccountandmac1.setClockin(null);
            }
            if (querydakamingxiandbydatebymac.getcDate()!=null)
            {
                //设置日期
                querybyaccountandmac1.setcDate(querydakamingxiandbydatebymac.getcDate().toString());
                //设置周几
                querybyaccountandmac1.setDayOfWeek(DateUtil.dateToWeek(querydakamingxiandbydatebymac.getcDate().toString()));
            } else {
                querybyaccountandmac1.setcDate(null);
                querybyaccountandmac1.setDayOfWeek(null);
            }
            if (querydakamingxiandbydatebymac.getAccount()!=null)
            {
                //设置账号
                querybyaccountandmac1.setAccount(querydakamingxiandbydatebymac.getAccount());
            }else {
                querybyaccountandmac1.setAccount(null);
            }
            if (querydakamingxiandbydatebymac.getSitename()!=null)
            {
                //设置站点
                querybyaccountandmac1.setSitename(querydakamingxiandbydatebymac.getSitename());
            }else {
                querybyaccountandmac1.setSitename(null);
            }
            if (querydakamingxiandbydatebymac.getDeviceid()!=null)
            {
                //设置设备id
                querybyaccountandmac1.setDeviceid(querydakamingxiandbydatebymac.getDeviceid());
            }else {
                querybyaccountandmac1.setDeviceid(null);
            }

            querydakamingxiandbydatebymacList1.add(querybyaccountandmac1);
        });
        writer.write(querydakamingxiandbydatebymacList1);
        writer.autoSizeColumn(1);//自动设置列宽度
        writer.autoSizeColumn(2);
        writer.autoSizeColumn(3);
        writer.autoSizeColumn(4);
        writer.autoSizeColumn(5);
        writer.autoSizeColumn(6);
       // writer.autoSizeColumnAll();

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        writer.flush(out);
        // 关闭writer，释放内存
        writer.close();
        IOUtils.closeQuietly(out);
        return out.toByteArray();

    }

    /**
     *
     * @param mac
     * @param date
     * @return
     */
    @Override
    public List<Querydakamingxiandbydatebymac> queryDakamingxiandbydatebymac(String mac, String date) {
        List<Querydakamingxiandbydatebymac> querydakamingxiandbydatebymacList=querydakamingxiandbydatebymacDao.queryBydatebyMacAndDate(mac,date);
        return querydakamingxiandbydatebymacList;
    }

    @Override
    public List<Querydakamingxiandbydatebymac> queryDakamingxiandbydatebymac(String date) {
        return querydakamingxiandbydatebymacDao.queryBydatebydate(date);
    }

    @Override
    public List<Querydakamingxiandbydatebymac> queryDakamingxiandbyWeekbymac(String account,String mac, String startDate, String endDate) {

        return querydakamingxiandbydatebymacDao.queryDakamingxiandbyWeekbymac(account,mac,startDate,endDate);
    }

    @Override
    public List<Querydakamingxiandbydatebymac> queryDakamingxiandbyWeek(String startDate, String endDate) {
        return querydakamingxiandbydatebymacDao.queryDakamingxiandbyWeek(startDate,endDate);
    }

    @Override
    public List<Dakamingxi> queryAll() {
        return dakamingxiDao.queryAll(new Dakamingxi());
    }

    @Override
    @Transactional
    public void updateall(List<Dakamingxi> dakamingxiList1) {
        dakamingxiDao.updateDakamingxiList(dakamingxiList1);
    }
}